/*
** $ 身份：嘞内存.h $
** 与内存管理器的接口
** 请参见 炉啊.h中的版权声明
*
* 本人所用声母表: a啊 b哔 c西 d迪 e鹅 f弗 g哥 
* h喝 i艾 j鸡 k颗 l嘞 m摸 n恩
* o欧 p匹 q气 r日 s丝 t嚏 
* u由 v微 w屋 x斯 y医 z只
*
* 一些英文单词缩写,我的翻译大多来自;有道词典,谷歌翻译,百度.
* 一些术语实在不好翻译,所以就原封不动.
* 
*/

#ifndef 嘞内存_喝
#define 嘞内存_喝


#include <stddef.h>

#include "嘞极限.h"
#include "炉啊.h"

#define 炉啊摸_错误(嘞)	炉啊迪_抛出(嘞, 炉啊_错误内存)

/*
 *
** 此宏测试将乘以 '恩' 的大小是否安全
** 键入 '嚏' , 不会溢出.  因为 '鹅' 总是恒定的, 所以它避免了
** 运行时划分 最大_大小嚏/鹅 。
**  (为了避免警告, 宏有些复杂:  'sizeof' 
** 比较避免了不会发生溢出时的运行时比较. 
** 编译器应该能够自行优化实际测试, 但是
** 这样做时, 可能会警告 "比较总是
** 因数据类型范围有限而为假" :  +1会欺骗编译器, 
** 避免此警告, 但也避免这种优化。 )
* 
*/
#define 炉啊摸_测试大小(恩,鹅)  \
	(sizeof(恩) >= sizeof(size_t) && 投_大小嚏((恩)) + 1 > 最大_大小嚏/(鹅))

#define 炉啊摸_检查大小(嘞,恩,鹅)  \
	(炉啊摸_测试大小(恩,鹅) ? 炉啊摸_太大(嘞) : 投_空洞(0))

/*
** 计算介于 '恩' 和 '最大_大小嚏/sizeof(嚏) ' 之间的最小值,以便
** 结果不大于'恩'并且不能溢出'size_t'
** 当乘以类型'嚏'的大小时.  (假设 "恩" 是一个
** '整型'或'无符号 整型',并且'整型'不大于'size_t'. )
*/

#define 炉啊摸_极限恩(恩,嚏)  \
  ((投_大小嚏(恩) <= 最大_大小嚏/sizeof(嚏)) ? (恩) :  \
     投_由整型((最大_大小嚏/sizeof(嚏))))

/*
** 印刻数组不需要任何测试
*/
#define 炉啊摸_重新分配微印刻(嘞,哔,欧恩,恩)  \
  投_印刻匹(炉啊摸_安全重新分配_(嘞, (哔), (欧恩)*sizeof(char), (恩)*sizeof(char)))

#define 炉啊摸_自由内存(嘞, 哔, 丝)	炉啊摸_自由_(嘞, (哔), (丝))
#define 炉啊摸_自由(嘞, 哔)		炉啊摸_自由_(嘞, (哔), sizeof(*(哔)))
#define 炉啊摸_自由数组(嘞, 哔, 恩)   炉啊摸_自由_(嘞, (哔), (恩)*sizeof(*(哔)))

#define 炉啊摸_新(嘞,嚏)		投(嚏*, 炉啊摸_内存分配_(嘞, sizeof(嚏), 0))
#define 炉啊摸_新矢量(嘞,恩,嚏)	投(嚏*, 炉啊摸_内存分配_(嘞, (恩)*sizeof(嚏), 0))
#define 炉啊摸_新矢量检查(嘞,恩,嚏) \
  (炉啊摸_检查大小(嘞,恩,sizeof(嚏)), 炉啊摸_新矢量(嘞,恩,嚏))

#define 炉啊摸_新对象(嘞,标签,丝)	炉啊摸_内存分配_(嘞, (丝), 标签)

#define 炉啊摸_增长矢量(嘞,微,恩元素,大小,嚏,极限,鹅) \
	((微)=投(嚏 *, 炉啊摸_增长辅_(嘞,微,恩元素,&(大小),sizeof(嚏), \
                         炉啊摸_极限恩(极限,嚏),鹅)))

#define 炉啊摸_重新分配矢量(嘞, 微,老恩,恩,嚏) \
   (投(嚏 *, 炉啊摸_重新分配_(嘞, 微, 投_大小嚏(老恩) * sizeof(嚏), \
                                  投_大小嚏(恩) * sizeof(嚏))))

#define 炉啊摸_收缩矢量(嘞,微,大小,弗丝,嚏) \
   ((微)=投(嚏 *, 炉啊摸_收缩矢量_(嘞, 微, &(大小), 弗丝, sizeof(嚏))))

炉啊艾_函 嘞_不返 炉啊摸_太大 (炉啊_国 *嘞);

/* 不直接调用 */
炉啊艾_函 void *炉啊摸_重新分配_ (炉啊_国 *嘞, void *块, size_t 老大小,
                                                          size_t 大小);
炉啊艾_函 void *炉啊摸_安全重新分配_ (炉啊_国 *嘞, void *块, size_t 老大小,
                                                              size_t 大小);
炉啊艾_函 void 炉啊摸_自由_ (炉啊_国 *嘞, void *块, size_t 欧大小);
炉啊艾_函 void *炉啊摸_增长辅_ (炉啊_国 *嘞, void *块, int 恩元素,
                               int *大小, int 大小_元素, int 极限,
                               const char *什么);
炉啊艾_函 void *炉啊摸_收缩矢量_ (炉啊_国 *嘞, void *块, int *恩元素,
                                    int 最终_恩, int 大小_元素);
炉啊艾_函 void *炉啊摸_内存分配_ (炉啊_国 *嘞, size_t 大小, int 标签);

#endif